package com.cirkana.serial.text;

import java.util.Date;
import java.util.List;
import java.util.Map;

import com.cirkana.ArrayUtil;
import com.cirkana.DateUtil;

public class TextSerializationBuilder {

	protected static final String NULL = "(null)";
	protected static final String KEY = "key";
	protected static final String VALUE = "value";

	StringBuilder stringBuilder;

	public TextSerializationBuilder() {
		this.stringBuilder = new StringBuilder("{");
	}

	public void append(String attribute, String string) {
		this.stringBuilder.append(attribute);
		this.stringBuilder.append("=");
		this.stringBuilder.append((string == null) ? NULL : string);
		this.stringBuilder.append(",");
	}

	public void append(String attribute, Integer integer) {
		this.append(attribute, (integer == null) ? null : Integer.toString(integer));
	}

	public void append(String attribute, Date date) {
		this.append(attribute, (date == null) ? NULL : DateUtil.getPresentationDate(date));
	}

	public void append(String attribute, Boolean bool) {
		this.append(attribute, (bool == null) ? NULL : Boolean.toString(bool));
	}

	public void append(String attribute, Double doubl) {
		this.append(attribute, (doubl == null) ? NULL : Double.toString(doubl));
	}

	public void append(String attribute, Float floa) {
		this.append(attribute, (floa == null) ? NULL : Float.toString(floa));
	}

	public void append(String attribute, ITextSerializable textSerializable) {
		this.append(attribute, (textSerializable == null) ? NULL : textSerializable.toText());
	}

	public void append(String attribute, String[] stringArray) {
		this.stringBuilder.append(attribute);
		this.stringBuilder.append("=");
		if (stringArray == null)
			this.stringBuilder.append(NULL);
		else {
			this.stringBuilder.append("[");
			for (int iii = 0; iii < stringArray.length; iii++)
				this.append("#" + iii, stringArray[iii]);
			if (this.stringBuilder.length() > 1)
				this.stringBuilder.delete(this.stringBuilder.length() - 1, this.stringBuilder.length());
			this.stringBuilder.append("],");
		}
	}

	public void append(String attribute, Integer[] integerArray) {
		this.stringBuilder.append(attribute);
		this.stringBuilder.append("=");
		if (integerArray == null)
			this.stringBuilder.append(NULL);
		else {
			this.stringBuilder.append("[");
			for (int iii = 0; iii < integerArray.length; iii++)
				this.append("#" + iii, integerArray[iii]);
			if (this.stringBuilder.length() > 1)
				this.stringBuilder.delete(this.stringBuilder.length() - 1, this.stringBuilder.length());
			this.stringBuilder.append("],");
		}
	}

	public void append(String attribute, Boolean[] booleanArray) {
		this.stringBuilder.append(attribute);
		this.stringBuilder.append("=");
		if (booleanArray == null)
			this.stringBuilder.append(NULL);
		else {
			this.stringBuilder.append("[");
			for (int iii = 0; iii < booleanArray.length; iii++)
				this.append("#" + iii, booleanArray[iii]);
			if (this.stringBuilder.length() > 1)
				this.stringBuilder.delete(this.stringBuilder.length() - 1, this.stringBuilder.length());
			this.stringBuilder.append("],");
		}
	}

	public void append(String attribute, Date[] dateArray) {
		this.stringBuilder.append(attribute);
		this.stringBuilder.append("=");
		if (dateArray == null)
			this.stringBuilder.append(NULL);
		else {
			this.stringBuilder.append("[");
			for (int iii = 0; iii < dateArray.length; iii++)
				this.append("#" + iii, dateArray[iii]);
			if (this.stringBuilder.length() > 1)
				this.stringBuilder.delete(this.stringBuilder.length() - 1, this.stringBuilder.length());
			this.stringBuilder.append("],");
		}
	}

	public void append(String attribute, Double[] doubleArray) {
		this.stringBuilder.append(attribute);
		this.stringBuilder.append("=");
		if (doubleArray == null)
			this.stringBuilder.append(NULL);
		else {
			this.stringBuilder.append("[");
			for (int iii = 0; iii < doubleArray.length; iii++)
				this.append("#" + iii, doubleArray[iii]);
			if (this.stringBuilder.length() > 1)
				this.stringBuilder.delete(this.stringBuilder.length() - 1, this.stringBuilder.length());
			this.stringBuilder.append("],");
		}
	}

	public void append(String attribute, Float[] floatArray) {
		this.stringBuilder.append(attribute);
		this.stringBuilder.append("=");
		if (floatArray == null)
			this.stringBuilder.append(NULL);
		else {
			this.stringBuilder.append("[");
			for (int iii = 0; iii < floatArray.length; iii++)
				this.append("#" + iii, floatArray[iii]);
			if (this.stringBuilder.length() > 1)
				this.stringBuilder.delete(this.stringBuilder.length() - 1, this.stringBuilder.length());
			this.stringBuilder.append("],");
		}
	}

	public void append(String attribute, Map<String, ?> hashtable) {
		this.stringBuilder.append(attribute);
		this.stringBuilder.append("=");
		if (hashtable == null)
			this.stringBuilder.append(NULL);
		else {
			this.stringBuilder.append("[");
			List<String> keys = ArrayUtil.sort(hashtable.keySet());
			for (String key : keys) {
				this.append(KEY, key);
				this.append(VALUE, ((ITextSerializable) hashtable.get(key)).toText());
			}
			if (this.stringBuilder.length() > 1)
				this.stringBuilder.delete(this.stringBuilder.length() - 1, this.stringBuilder.length());
			this.stringBuilder.append("],");
		}
	}

	public void append(String attribute, List<?> list) {
		this.stringBuilder.append(attribute);
		this.stringBuilder.append("=");
		if (list == null)
			this.stringBuilder.append(NULL);
		else {
			this.stringBuilder.append("[");
			for (int iii = 0; iii < list.size(); iii++)
				this.append("#" + iii, ((ITextSerializable) list.get(iii)));
			this.stringBuilder.append("],");
		}
	}

	public String getTextSerialization() {
		if (this.stringBuilder.length() > 1)
			this.stringBuilder.delete(this.stringBuilder.length() - 1, this.stringBuilder.length());
		this.stringBuilder.append("}");
		return this.stringBuilder.toString();
	}
}
